using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;

public class BattleController : MonoBehaviour
{
    public GameObject luna;
    public GameObject monster;

    public SpriteRenderer rendererLuna;
    public SpriteRenderer rendererMonster;

    private Animator animatorLuna;
    private Animator animatorMonster;

    private Vector2 initPositionLuna;
    private Vector2 initPositionMonster;

    private MonsterController monsterController;

    public GameObject skillsPanel;
    public GameObject battleArea;

    public GameObject perfabHeal;
    public GameObject perfabSkill;

    #region 音效
    private AudioClip audioLunaAttack;
    private AudioClip audioLunaDamage;
    private AudioClip audioLunaDie;
    private AudioClip audioLunaRecoverHP;
    private AudioClip audioMonsterAttack;
    private AudioClip audioMonsterDamage;
    private AudioClip audioRedemption;
    #endregion

    void Awake()
    {
        this.animatorLuna = this.luna.GetComponent<Animator>();
        this.animatorMonster = this.monster.GetComponent<Animator>();
        this.rendererLuna = this.luna.GetComponent<SpriteRenderer>();
        this.rendererMonster = this.monster.GetComponent<SpriteRenderer>();
        this.initPositionLuna = this.luna.transform.localPosition;
        this.initPositionMonster = this.monster.transform.localPosition;
        this.monsterController = this.monster.GetComponent<MonsterController>();
        #region 音效
        this.audioLunaAttack = Resources.Load<AudioClip>("Audios/Luna/Attack");
        this.audioLunaDamage = Resources.Load<AudioClip>("Audios/Luna/Damage");
        this.audioLunaDie = Resources.Load<AudioClip>("Audios/Luna/Die");
        this.audioLunaRecoverHP = Resources.Load<AudioClip>("Audios/Luna/RecoverHP");
        this.audioMonsterAttack = Resources.Load<AudioClip>("Audios/Monster/Attack");
        this.audioMonsterDamage = Resources.Load<AudioClip>("Audios/Monster/Damage");
        this.audioRedemption = Resources.Load<AudioClip>("Audios/Skill/Redemption");
        #endregion
    }

    void OnEnable()
    {
        this.rendererMonster.DOFade(1, 0);
        GameManager.Instance.PlayBattleMusic();
    }

    private void Prepare()
    {
        this.skillsPanel.SetActive(false);
    }

    private void After()
    {
        this.skillsPanel.SetActive(true);
    }

    #region 攻击
    public void Attack()
    {
        StartCoroutine(nameof(AttackCore));
    }

    public IEnumerator AttackCore()
    {
        Prepare();
        LunaAttack();
        yield return new WaitForSeconds(2);
        MonsterAttack();
        yield return new WaitForSeconds(1.2f);
        After();
    }

    public void LunaAttack()
    {
        StartCoroutine(nameof(LunaAttackCore));
    }

    private IEnumerator LunaAttackCore()
    {
        this.animatorLuna.CrossFade(Defines.Forward, 0);
        this.luna.transform.DOLocalMove(initPositionMonster + new Vector2(1.5f, 0), 0.5f).OnComplete(() =>
        {
            this.animatorLuna.CrossFade(Defines.Attack, 0);
            GameManager.Instance.PlaySound(this.audioLunaAttack);
            StartCoroutine(nameof(LunaBackward));
        });
        yield return null;
    }

    private IEnumerator LunaBackward()
    {
        yield return new WaitForSeconds(0.4f);

        /* Monster受伤闪烁并减少生命值 */
        GameManager.Instance.PlaySound(this.audioMonsterDamage);
        this.rendererMonster.DOFade(0.5f, 0.1f).OnComplete(() =>
        {
            this.rendererMonster.DOFade(1, 0.1f);
        });
        yield return new WaitForSeconds(0.4f);
        this.rendererMonster.DOFade(0.5f, 0.1f).OnComplete(() =>
        {
            this.rendererMonster.DOFade(1, 0.1f);
        });
        var ad = LunaStatusManager.Instance.GetAD();
        this.monsterController.ChangeHP(-ad);
        CheckMonsterStatus();
        /* -------- */

        this.animatorLuna.CrossFade(Defines.Backward, 0);
        this.luna.transform.DOLocalMove(initPositionLuna, 0.5f).OnComplete(() =>
        {
            this.animatorLuna.CrossFade(Defines.Idle, 0);
        });
    }

    private void MonsterAttack()
    {
        StartCoroutine(nameof(MonsterAttackCore));
    }

    private IEnumerator MonsterAttackCore()
    {
        GameManager.Instance.PlaySound(this.audioMonsterAttack);
        this.monster.transform.DOLocalMove(initPositionLuna - new Vector2(1, 0), 0.5f).OnComplete(() =>
        {
            if (LunaStatusManager.Instance.CanDefend())
            {
                // Luna防御
                this.animatorLuna.SetBool(Defines.Defend, true);
            }
            else
            {
                /* Luna受伤并减少生命值 */
                this.animatorLuna.Play(Defines.Damage);
                GameManager.Instance.PlaySound(this.audioLunaDamage);
                var ad = this.monsterController.GetAD();
                LunaStatusManager.Instance.ChangeHP(-ad);
            }
        });
        yield return new WaitForSeconds(0.7f);
        this.monster.transform.DOLocalMove(initPositionMonster, 0.5f).OnComplete(() =>
        {
            this.animatorLuna.SetBool(Defines.Defend, false);
        });
    }
    #endregion

    public void Skill()
    {
        StartCoroutine(nameof(SkillCoroutine));
    }

    IEnumerator SkillCoroutine()
    {
        var skillInfo = LunaStatusManager.Instance.GetSkillInfo(Defines.Redemption) as Redemption;
        // 消耗蓝
        var enoughMP = LunaStatusManager.Instance.ChangeMP(-skillInfo.CostMP);

        if (enoughMP)
        {
            Prepare();
            /* 动画 */
            this.animatorLuna.SetBool(Defines.Skill, true);
            GameManager.Instance.PlaySound(this.audioRedemption);
            GameManager.Instance.PlaySound(this.audioMonsterDamage);
            var obj = Instantiate(perfabSkill, this.monster.transform);
            obj.transform.localPosition = new Vector2(0, -0.5f);
            yield return new WaitForSeconds(2.5f);
            this.animatorLuna.SetBool(Defines.Skill, false);
            /* --- */

            // Monster受伤减少生命值
            this.monsterController.ChangeHP(-skillInfo.AP);
            this.CheckMonsterStatus();

            yield return new WaitForSeconds(0.667f);
            After();
        }
    }

    public void RecoverHP()
    {
        StartCoroutine(nameof(RecoverHPCoroutine));
    }

    IEnumerator RecoverHPCoroutine()
    {
        var skillInfo = LunaStatusManager.Instance.GetSkillInfo(Defines.RecoverHP) as RecoverHP;
        // 消耗蓝
        var enoughMP = LunaStatusManager.Instance.ChangeMP(-skillInfo.CostMP);
        if (enoughMP)
        {
            Prepare();
            /* 动画 */
            GameManager.Instance.PlaySound(this.audioLunaRecoverHP);
            this.animatorLuna.SetBool(Defines.Defend, true);
            var obj = Instantiate(perfabHeal, this.luna.transform);
            obj.transform.localPosition = Vector2.zero;
            yield return new WaitForSeconds(3.167f);
            this.animatorLuna.SetBool(Defines.Defend, false);
            /* --- */
            // 恢复血
            LunaStatusManager.Instance.ChangeHP(skillInfo.RecoverValue);
            After();
        }
    }

    public void Escape()
    {
        this.skillsPanel.SetActive(false);
        StartCoroutine(nameof(EscapeCoroutine));
    }

    IEnumerator EscapeCoroutine()
    {

        this.luna.transform.DOLocalMove(initPositionLuna + new Vector2(3, 0), 0.3f).OnComplete(() =>
        {
            Exit();
        });
        yield return null;
    }

    private void Exit()
    {
        this.battleArea.SetActive(false);
        gameObject.SetActive(false);
        // 恢复用于下次进入
        this.luna.transform.DOLocalMove(initPositionLuna, 0);
        this.skillsPanel.SetActive(true);
        LunaStatusManager.Instance.LunaState = LunaState.Normal;
        GameManager.Instance.PlayNormalMusic();
    }

    private void CheckMonsterStatus()
    {
        if(this.monsterController.IsDead())
        {
            this.rendererMonster.DOFade(0, 0.5f).OnComplete(() =>
            {
                Destroy(GameManager.Instance.CurrentMonster);
                Exit();
                // 恢复用于下一个怪物，因多个怪物在战斗状态用的一个游戏对象
                this.monsterController.CurrentHP = 100.0f;
            });
        }
    }
}
